home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / pgmprot.com / SERNO.ASM < prev    next >
Encoding:
Assembly Source File  |  1988-11-05  |  12.2 KB  |  347 lines

  1.         page    55,132
  2.         Title    Copyright and Serial Number Module
  3.         Subttl    SERNO.ASM
  4. ;-----------------------------------------------------------------------
  5. ;    Copyright and Serial Number Module
  6. ;-----------------------------------------------------------------------
  7. ;
  8. ;    This module implements a protected embedded copyright message,
  9. ;    serial number, and version number scheme. Its purpose is as 
  10. ;    described below.
  11. ;
  12. ;    Copyright Message
  13. ;    -----------------
  14. ;
  15. ;    A standard copyright message is included in this module. This
  16. ;    copyright message is a standard C null-terminated string that is
  17. ;    included in the TEXT segment (code) rather than in the BSS segment
  18. ;    with all other initialized variables.
  19. ;
  20. ;    The copyright message is intended to be a standard copyright used
  21. ;    with all distributed software. It may be changed provided that the
  22. ;    software that this module is used with is relinked, and provided
  23. ;    that the SETVER utility is reassembled/recompiled with the new
  24. ;    module.
  25. ;
  26. ;    The copyright message, as it is assembled with this module, is
  27. ;    assembled such that an XOR checksum of the copyright message
  28. ;    characters will be nonzero. This signals that one of two possible
  29. ;    problems exist: (1) the copyright message has been tampered with
  30. ;    or removed, or (2) the program file has not yet been serialized.
  31. ;
  32. ;    This module provides a function called GetCopyright() that returns
  33. ;    a FAR pointer to the copyright message. This pointer will be NULL
  34. ;    if either of the above two conditions exists, and the caller of
  35. ;    GetCopyright() then has the option of terminating the program
  36. ;    because of an invalid copyright. The pointer must be FAR because
  37. ;    C will normally expect to find it in the data segment addressed
  38. ;    via the DS register.
  39. ;
  40. ;    If GetCopyright() returns a nonzero FAR pointer, then the copyright
  41. ;    message and the serial and version numbers are intact, and the caller
  42. ;    may elect to display the copyright message on the screen. Note that 
  43. ;    the GetCopyright() function is the ONLY function that verifies the 
  44. ;    XOR checksum, and should be called to verify that the program file 
  45. ;    has not been modified and that the serial and version numbers are 
  46. ;    valid even if the copyright message is not to be displayed.
  47. ;
  48. ;    Serial Number
  49. ;    -------------
  50. ;
  51. ;    Provision is made for a ten-digit numeric serial number encoded as a
  52. ;    long integer. The function GetSerialNumber() returns this serial 
  53. ;    number, which may be displayed on the screen or used programmatically
  54. ;    to make decisions based on the serial number.
  55. ;
  56. ;    Version Number
  57. ;    --------------
  58. ;
  59. ;    Provision is made for a five-digit numeric version number encoded as
  60. ;    an unsigned integer. The function GetVersionNumber() returns this 
  61. ;    version number, which may be displayed on the screen or used 
  62. ;    programmatically to make decisions based on the version number.
  63. ;
  64. ;    Serialization
  65. ;    -------------
  66. ;
  67. ;    This module assumes that a separate program will be used to serialize
  68. ;    the program. This serialization program (SETVER) performs three 
  69. ;    functions:
  70. ;
  71. ;    (1) It inserts the proper XOR checksum on the copyright message,
  72. ;        which signals the program at run-time that the copyright message
  73. ;        has not been tampered with.
  74. ;
  75. ;    (2) It inserts the desired serial number, which is NOT stored in
  76. ;        standard LSB...MSB form. If the serial number is displayed on
  77. ;        the screen, a fairly competent hacker, finding that the serial
  78. ;        number is not encoded literally (in ASCII), will assume that
  79. ;        it is stored in binary and may search for the binary sequence.
  80. ;        In this way the serial number may be changed. To defeat this,
  81. ;        the second and fourth bytes of the serial number are swapped,
  82. ;        which will not convert to anything even close to the proper
  83. ;        serial number.
  84. ;
  85. ;    (3) It inserts the desired version number, which is stored in
  86. ;        standard LSB...MSB integer form. 
  87. ;
  88. ;    (4) A standard checksum will be performed on the copyright and
  89. ;        serial/version number areas, and a special checksum byte 
  90. ;        adjusted so that the .EXE file checksum remains correct. If 
  91. ;        this is not done, the DOS EXEC loader may reject the .EXE file.
  92. ;
  93. ;    Because the DOS EXEC loader performs all segment fixups, the
  94. ;    serialization program must search for a key field. The copyright
  95. ;    message serves as the search key. This same module is used by the
  96. ;    serialization program, so there is no possibility of invalidating
  97. ;    the key. 
  98. ;
  99. ;    Therefore, if either the serial number or copyright message are
  100. ;    changed, DOS may refuse to load the program. If someone familiar
  101. ;    enough with the .EXE file format knows about the .EXE checksum
  102. ;    and corrects it, the XOR checksum will still prevent the program
  103. ;    from operating if this is desired by the caller of GetCoptright().
  104. ;    Since the checksum scheme is unknown, it will be difficult to install
  105. ;    the proper XOR checksum to defeat the protection.
  106. ;
  107. ;    While these measures may not prevent a sophisicated and determined
  108. ;    individual from modifying either the copyright or the serial number,
  109. ;    it should provide protection from most users.
  110. ;
  111. ;    Assembly
  112. ;    --------
  113. ;
  114. ;    This module must be assembled with the Microsoft Macro Assmbler
  115. ;    (MASM) Version 5.1 or later. The MASM command line is as follows:
  116. ;
  117. ;        MASM /Ml /DMODEL=model serno;
  118. ;
  119. ;    where 'model' is one of SMALL, MEDIUM, COMPACT, or LARGE. The
  120. ;    assembled module is intended to be linked with a C program compiled
  121. ;    with Microsoft C V5.1 or later.
  122. ;
  123. ;-----------------------------------------------------------------------
  124.  
  125. %        .MODEL    MODEL,C
  126.  
  127.         page
  128. ;-----------------------------------------------------------------------
  129. ;    Serial Number and Checksum Structure
  130. ;-----------------------------------------------------------------------
  131.  
  132. sn_blk        struc
  133. SN_Data        dd    0    ;serial number, bytes 2 and 4 swapped
  134. VN_Data        dw    0    ;version number
  135. SN_Cksm        db    0    ;copyright and serial number checksum
  136. EXE_Cksm    db    0    ;DOS .EXE file checksum correction
  137. sn_blk        ends
  138.  
  139. ;-----------------------------------------------------------------------
  140. ;    Code Segment Definition
  141. ;-----------------------------------------------------------------------
  142.  
  143.         .CODE
  144.  
  145.         page
  146. ;-----------------------------------------------------------------------
  147. ;    Verify and Return Pointer To Copyright Message
  148. ;-----------------------------------------------------------------------
  149. ;
  150. ;    This function will return a FAR pointer to the copyright message.
  151. ;    A far pointer is used because the copyright message is not in
  152. ;    the standard C data segment; rather, it is in the code segment.
  153. ;    This function will return a NULL pointer if the copyright message
  154. ;    or serial number have not been initialized by the serialization
  155. ;    utility or if either has been tampered with.
  156. ;
  157. ;    This function is declared and used as follows.
  158. ;
  159. ;    /* function prototype */
  160. ;
  161. ;    char far *GetCopyright (void);
  162. ;
  163. ;    /* example usage */
  164. ;
  165. ;    char far *p;
  166. ;
  167. ;    if ((p = GetCopyright ()) == (char far *) NULL)
  168. ;        {
  169. ;        /* print error and/or abort execution */
  170. ;        ......
  171. ;        }
  172. ;    else
  173. ;        printf ("%Fs", p);
  174. ;
  175. ;    The 'F' in the printf() format specification tells printf() that
  176. ;    'p' is a far pointer.
  177. ;
  178. ;-----------------------------------------------------------------------
  179.  
  180. GetCopyright    proc
  181.         mov    bx,offset @code:_CopyrightMsg    ;point to copyright message
  182.         push    cs                ;** stack far pointer to message
  183.         push    bx                ;*
  184.         if    @CodeSize            ;if large code model
  185.         push    cs                ;stack segment first
  186.         endif
  187.         call    near ptr _CPSUM            ;calculate the XOR checksum
  188.         add    sp,4                ;clear stack
  189.         mov    dx,cs                ;get segment address to DX
  190.         cmp    al,byte ptr cs:sn.SN_Cksm    ;valid checksum?
  191.         mov    ax,bx                ;get offset to AX
  192.         jz    short GetCopyright0        ;yes, return segment and offset
  193.         sub    ax,ax                ;** no, return null pointer
  194.         mov    dx,ax                ;*
  195. GetCopyright0:
  196.         ret
  197. GetCopyright    endp
  198.  
  199.         page
  200. ;-----------------------------------------------------------------------
  201. ;    Return Pointer To Copyright Message
  202. ;-----------------------------------------------------------------------
  203. ;
  204. ;    This function will return a FAR pointer to the copyright message.
  205. ;    A far pointer is used because the copyright message is not in
  206. ;    the standard C data segment; rather, it is in the code segment.
  207. ;    This function will always return a valid far pointer to the
  208. ;    copyright message, and is intended to be used by the serialization
  209. ;    program to locate the copyright message in the target file.
  210. ;
  211. ;    This function is declared and used as follows.
  212. ;
  213. ;    /* function prototype */
  214. ;
  215. ;    char far *_CPPTR (void);
  216. ;
  217. ;    /* example usage */
  218. ;
  219. ;    char far *p;
  220. ;
  221. ;    p = _CPPTR ();
  222. ;
  223. ;-----------------------------------------------------------------------
  224.  
  225. _CPPTR        proc
  226.         mov    dx,cs                ;** return far pointer to copyright
  227.         mov    ax,offset @code:_CopyrightMsg    ;*
  228.         ret                    ;and return
  229. _CPPTR        endp
  230.         
  231.         page
  232. ;-----------------------------------------------------------------------
  233. ;    Return Serial Number
  234. ;-----------------------------------------------------------------------
  235. ;
  236. ;    This function will return the program serial number as a standard
  237. ;    C long integer value. This value may be printed using printf().
  238. ;
  239. ;    The function GetCopyright() should always be called first to
  240. ;    determine if the serial number is valid.
  241. ;
  242. ;    The function is declared and used as follows.
  243. ;
  244. ;    /* function prototype */
  245. ;
  246. ;    long cdecl GetSerialNumber (void);
  247. ;
  248. ;    /* example usage */
  249. ;
  250. ;    printf ("Serial Number %lu", GetSerialNumber ());
  251. ;
  252. ;-----------------------------------------------------------------------
  253.  
  254. GetSerialNumber    proc
  255.         mov    ax,word ptr cs:sn.SN_Data    ;** get serial number to DX:AX
  256.         mov    dx,word ptr cs:sn.SN_Data+2    ;*
  257.         xchg    ah,dh                ;swap second and fourth bytes
  258.         ret                    ;and return
  259. GetSerialNumber    endp
  260.  
  261.         page
  262. ;-----------------------------------------------------------------------
  263. ;    Return Version Number
  264. ;-----------------------------------------------------------------------
  265. ;
  266. ;    This function will return the program version number as a standard
  267. ;    C unsigned integer value. This value may be printed using printf().
  268. ;
  269. ;    The function GetCopyright() should always be called first to
  270. ;    determine if the version number is valid.
  271. ;
  272. ;    The function is declared and used as follows.
  273. ;
  274. ;    /* function prototype */
  275. ;
  276. ;    unsigned int cdecl GetVersionNumber (void);
  277. ;
  278. ;    /* example usage */
  279. ;
  280. ;    printf ("Version Number %u", GetVersionNumber ());
  281. ;
  282. ;-----------------------------------------------------------------------
  283.  
  284. GetVersionNumber proc
  285.         mov    ax,word ptr cs:sn.VN_Data    ;get version number to AX
  286.         ret                    ;and return
  287. GetVersionNumber endp
  288.  
  289.         page
  290. ;-----------------------------------------------------------------------
  291. ;    Calculate Copyright XOR Checksum
  292. ;-----------------------------------------------------------------------
  293. ;
  294. ;    This function will calculate the XOR checksum on the copyright
  295. ;    message and return it. For copyright and checksum verification,
  296. ;    this value should be compared to that stored in SN_Cksm; for
  297. ;    serialization, it should be stored at the copyright message
  298. ;    plus the offset stored in SN_Cksm.
  299. ;
  300. ;    Synopsis:
  301. ;
  302. ;        sum = _CPSUM (ptr);
  303. ;
  304. ;        int sum;        XOR checksum of copyright and 
  305. ;                    serial number, rotated left once
  306. ;        char far *ptr;        far pointer to copyright message
  307. ;
  308. ;-----------------------------------------------------------------------
  309.  
  310. _CPSUM        proc    uses ds si, address:far ptr
  311.         lds    si,address            ;get address of string
  312.         sub    ah,ah                ;clear XOR checksum
  313.  
  314.         ; perform checksum on copyright string
  315.  
  316. _CPSUM0:
  317.         lodsb                    ;get byte
  318.         xor    ah,al                ;accumulate into checksum
  319.         or    al,al                ;at end of copyright string?
  320.         jnz    _CPSUM0                ;no, loop
  321.  
  322.         ; perform checksum on serial number
  323.  
  324.         mov    cx,SN_Cksm            ;get offset to checksum byte
  325. _CPSUM1:
  326.         lodsb                    ;get byte
  327.         xor    ah,al                ;accumulate into checksum
  328.         loop    _CPSUM1                ;loop up to checksum byte
  329.         mov    al,ah                ;** get checksum to AX
  330.         mov    ah,cl                ;*
  331.         ret                    ;and return it
  332. _CPSUM        endp
  333.  
  334.         page
  335. ;-----------------------------------------------------------------------
  336. ;    Copyright Message and Serial Number Data Area
  337. ;-----------------------------------------------------------------------
  338.  
  339. _CopyrightMsg    label    byte                ;copyright message
  340.         db    "Copyright (c) 1988 "
  341.         db    "Quid Pro Quo Software. "
  342.         db    "All rights reserved.",0
  343. sn        sn_blk    <>                ;serial number block
  344.  
  345.         end
  346.  
  347.